<?php

namespace App\Models;

use App\Models\Users\MoneyLog;
use App\Services\Data;
use Carbon\Carbon;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Model;

/**
 *
 * status  订单状态0 已下单 1 预约 2 进行中 3 取消 4 已完成 5 已评价
 * order_type 订单类型 1预约订单 2咨询订单
 */
class OrderAppoint extends BasicModel
{
	use HasDateTimeFormatter;
    use SoftDeletes;

    protected $table = 'order_appoint';


    protected  array $price_map=[
        1=>'text_price',
        2=>'voice_price',
        3=>'voice_price',
    ];

    protected  array $consult_way=[
        1=>'文字咨询',
        2=>'语音咨询',
        3=>'视频咨询'
    ];
    /**
     * @throws \Exception
     */
    public function createOrder($data): Model|OrderAppoint
    {

        $data = $this->checkOrder($data);

        if($data['order_type']==1){
            $order= OrderAppoint::create($data);
            $order->order_no= 'Z'.str_pad($order->id,5,'0',STR_PAD_LEFT).Data::orderTimeNumber();
            $order->save();
            return $order; //预约订单直接返回
        }

        //查找有没有当天预约订单
        $order = self::where(['day'=>date('Ymd'),'user_id'=>$data['user_id'],'appoint_id'=>$data['appoint_id'],'status'=>1])->orderBy('id')->first();
        if(empty($order)){
            $order= OrderAppoint::create($data);
            $order->order_no= 'Z'.str_pad($order->id,5,'0',STR_PAD_LEFT).Data::orderTimeNumber();
            $order->save();
        }
        $order->begin_time=Carbon::now()->toDateTimeString();
        $order->status=2;
        $order->save();

        if($data['consult_way'] == 1) {
            $desc = $this->consult_way[$data['consult_way']] . '消费';
            (new MoneyLog())->add($data['user_id'], -$order->total_price, $desc, 2, $order->id);
        }else{
//            $user = User::query()->find($data['user_id']);
//            $user->money = $user->money - $order->price;
//            if($user->money < 0) throw new \Exception('余额不足');
//            $user->save();
        }
        return $order;
    }


    public function list($uid,$status){
        $list=OrderAppoint::query()->with(['user'=>function($query){
            $query->select(['id','name','avatar']);
        },'teacher'=>function($query){
            $query->select(['id','name','avatar']);
        }])->where(function ($query) use ($uid) {
          $query->where(['user_id'=>$uid])->orWhere(['appoint_id'=>$uid]);
        });
        if($status <= 3) $list->where('status','<=',3);
        if($status == 4) $list->whereIn('status',[4,5]);
        $list->orderByDesc('id');
        return $list->paginate(10);

    }


    public function accept($uid,$oid){
        $order=OrderAppoint::query()->where(['id'=>$oid,'appoint_id'=>$uid,'status'=>0])->first();
        if(empty($order)) return false;
        $order->status=1;
        return $order->save();
    }

    public function cancel($uid,$oid){
        $order=OrderAppoint::query()->where(['id'=>$oid,'user_id'=>$uid,'status'=>0])->first();
        if(empty($order)) return false;

//        if($order->consult_way == 1) {
//            (new MoneyLog())->add($order->appoint_id, $order->price, '订单退款', 2, $oid);
//        }
        $order->status=3;
        return $order->save();

    }

    public function confirm($uid,$oid,$duration){
        $order=OrderAppoint::query()->where(['id'=>$oid,'user_id'=>$uid,'status'=>2])->first();
        if(empty($order)) return false;
        $order->total_price=bcmul($duration, $order->price);
        User::query()->find($order->appoint_id)->increment('order_num');
        (new MoneyLog())->add($order->appoint_id, $order->total_price, '咨询收入', 3, $oid);
        (new MoneyLog())->add($order->user_id, -$order->total_price, '咨询消费', 2, $oid);
        $order->status=4;
        $order->end_time = Carbon::now()->toDateTimeString();
        $order->duration_time=$duration;
        return $order->save();

    }
    public function rate($uid,$oid,$comment,$grade){
        $order=OrderAppoint::query()->where(['id'=>$oid,'user_id'=>$uid,'status'=>4])->first();
        if(empty($order)) return false;
        $order->status=5;
        $order->comment=$comment;
        $order->grade=$grade;
        return $order->save();

    }

    public function charging($uid,$oid){
        $order=OrderAppoint::query()->where(['id'=>$oid,'user_id'=>$uid,'status'=>2])->first();
        if(empty($order)) throw new \Exception('订单错误');
        $user = User::query()->with('extend')->find($uid);
        if($order->consult_way!=1){
            $order->duration_time++;
            $order->total_price += $order->price;
            $order->save();
            $user->money = $user->money - $order->price;
            if($user->money < 0) throw new \Exception('余额不足');
            $user->save();
            $this->addTeacherTime($order->appoint_id);
        }
        return true;
    }


    private function checkOrder($data){
        $user=User::query()->find($data['user_id']);
        $teacher=User::query()->with('extend')->where(['id'=>$data['appoint_id']])->first();
        if($data['consult_type']==1 && $teacher->xinli != 1)  throw new \Exception('身份错误1');
        if($data['consult_type']==2 && $teacher->zhanbu != 1)  throw new \Exception('身份错误2');
        if($data['consult_type']==3 && $teacher->qingting != 1)  throw new \Exception('身份错误3');
        $price_map=$this->price_map[$data['consult_way']];
        $price = $teacher->extend->{$price_map};
        //文字全部扣费 语音扣1分钟
        if($data['consult_way']==1) {
            $order_price = bcmul($teacher->extend->{$price_map}, $data['buy_time'], 2);
        }else{
            $order_price = bcmul($teacher->extend->{$price_map}, $data['buy_time'], 2);
        }
        if($user->money<$order_price) throw new \Exception('余额不足');
        $data['price']= $price;
        $data['total_price']= $data['consult_way']!=1 ? 0 : $order_price;
        $sdate=Carbon::parse($teacher->extend->take_order_day_begin ?? date('Ymd'));
        $edate=Carbon::parse($teacher->extend->take_order_day_end ?? date('Ymd'));
        if(!Carbon::now()->between($sdate,$edate,true)) throw new \Exception('不在该老师接单日期');
        return $data;
    }

    public function user()
    {
        return $this->hasOne(User::class, 'id', 'user_id');
    }
    public function teacher()
    {
        return $this->hasOne(User::class, 'id', 'appoint_id');
    }

    private function addTeacherTime($uid,$time=1){
        $user_ext=UsersExtend::find($uid);
        $user_ext->duration+=$time;
        $user_ext->save();
    }
}
